package edu.whu.demo.controller;


import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import com.baomidou.mybatisplus.core.metadata.IPage;
import edu.whu.demo.domain.User;
import edu.whu.demo.domain.UserRegister;
import edu.whu.demo.exception.AccountException;
import edu.whu.demo.security.JwtTokenUtil;
import edu.whu.demo.service.impl.MailService;
import edu.whu.demo.service.impl.MessageServiceImpl;
import edu.whu.demo.service.impl.UserRegisterServiceImpl;
import edu.whu.demo.service.impl.UserServiceImpl;
import io.jsonwebtoken.Claims;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.parameters.P;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author 
 * @since 2022-11-24
 */
@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    UserServiceImpl userService;

    @Autowired
    JwtTokenUtil jwtTokenUtil;

    @Autowired
    AuthenticationManager authenticationManager;

    @Autowired
    UserRegisterServiceImpl userRegisterService;

    @Autowired
    MailService mailService;


    @Value("${rsa.private_key}")
    private String privateKey;

    @ApiOperation("设置图片")
    @PostMapping("/setpic/{uid}")
    public ResponseEntity<String> uploadPicture(@PathVariable Long uid,@RequestPart("pic") MultipartFile pic) throws AccountException, IOException {
        return ResponseEntity.ok(userService.uploadPicture(uid,pic));
    }
    @ApiOperation("根据id获得用户")
    @GetMapping("/{uid}")
    public User getUser(@PathVariable Long uid){
        return userService.getAccount(uid);
    }

    @ApiOperation("根据token获得用户")
    @GetMapping("/token")
    public User getUserFromToken(@RequestHeader("Authorization") String header){
        System.out.println(header);
        final String token = header.substring(7);
        //解析token，如果token不合法会抛出异常
        Claims claims = jwtTokenUtil.getClaimFromToken(token);
        String name = claims.getSubject();
        System.out.println("name "+name);
        return userService.getUserByName(name);
    }

    // 修改后的登录，前端传的加密后的名字和密码，后端解密后验证
    @ApiOperation("登录")
    @PostMapping("/login")
    public ResponseEntity<String> login(@RequestParam String name, @RequestParam String password){
        RSA rsa = new RSA(privateKey, null);
        String userName = new String(rsa.decrypt(name, KeyType.PrivateKey));
        String userPassword = new String(rsa.decrypt(password, KeyType.PrivateKey));
        System.out.println(userName+"    "+userPassword);

        authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(userName, userPassword));
        final String token = jwtTokenUtil.generateToken(userName);
        return ResponseEntity.ok(token);
    }


    @ApiOperation("删除用户")
    @DeleteMapping("/{id}")
    @PreAuthorize("hasRole('admin')")
    public void deleteUser(@PathVariable Long id){
        userService.deleteAccount(id);
    }

    @ApiOperation("修改用户名")
    @PutMapping("/name/{id}")
    public void updateUserName(@PathVariable Long id,@RequestParam String name) throws AccountException {
        User user = userService.getAccount(id);
        RSA rsa = new RSA(privateKey, null);
        String userName = new String(rsa.decrypt(name, KeyType.PrivateKey));
        user.setName(userName);
        userService.updateAccount(id, user);
    }

    @ApiOperation("修改用户邮箱")
    @PutMapping("/email/{id}")
    public void updateUserEmail(@PathVariable Long id,@RequestParam String email) throws AccountException {
        User user = userService.getAccount(id);
        RSA rsa = new RSA(privateKey, null);
        String newEmail = new String(rsa.decrypt(email, KeyType.PrivateKey));
        user.setEmail(newEmail);
        userService.updateAccount(id, user);
    }

    @ApiOperation("查找用户信息")
    @GetMapping("")
    @PreAuthorize("hasRole('admin')")
    public IPage<User> searchUser(@RequestParam Integer pageNum,
                                  @RequestParam Integer pageSize,
                                  @RequestParam(required=false) String keyword,
                                  @RequestParam(required=false) Boolean order){
        Map<String,Object> condition = new HashMap<>();
        if(keyword != null){
            condition.put("keyword",keyword);
        }
        if(order != null){
            condition.put("order",order);
        }
        return userService.findAccount(condition,pageNum,pageSize);
    }

    @ApiOperation("发送验证码")
    @PostMapping("/register/sms")
    public ResponseEntity<String> userRegisterSms(@RequestParam String name,
                                                  @RequestParam String email) throws ParseException {
        int sms = (int)((Math.random()*9+1)*10000);
        if (userService.userRegisterSms(name)){
            mailService.sendSimpleMail("2020302111336@whu.edu.cn",email,"**@outlook.com","注册验证码","您的验证码为:"+sms);
            if (userRegisterService.deleteUserRegister(name)){
                userRegisterService.addUserRegister(name,email,sms);
            }
            return ResponseEntity.noContent().build();
        }else {
            return ResponseEntity.ok("用户已存在");
        }
    }


    @ApiOperation("注册")
    @PostMapping("/register")
    public ResponseEntity<String> userRegister(@RequestParam String name,
                                               @RequestParam String password,
                                               @RequestParam String sms) throws ParseException {
        RSA rsa = new RSA(privateKey, null);
        String smsTemp = new String(rsa.decrypt(sms,KeyType.PrivateKey));
        int s = Integer.parseInt(smsTemp);
        String userName = new String(rsa.decrypt(name,KeyType.PrivateKey));
        String userPassword = new String(rsa.decrypt(password, KeyType.PrivateKey));
        UserRegister userRegister = userRegisterService.selectById(userName);
        if (userRegisterService.deleteUserRegister(userName)){
            return ResponseEntity.ok("验证码过期");
        }else if (userRegister==null){
            return ResponseEntity.ok("验证码错误");
        }else if (userRegister.getSms()!=s){
            return ResponseEntity.ok("验证码错误");
        }else {
            User user = new User();
            user.setName(userName);
            user.setEmail(userRegister.getEmail());
//            user.setPassword(password);
            user.setPassword(userPassword);
            userService.userRegister(user);
            userRegisterService.deleteUserRegisterOk(userName);
            return ResponseEntity.ok("注册成功");
        }
    }

    @ApiOperation("修改密码")
    @PostMapping("/reset")
    public ResponseEntity<String> userPasswordChange(@RequestParam String name,
                                                     @RequestParam String password,
                                                     @RequestParam String newPassword){
        RSA rsa = new RSA(privateKey, null);
        String userName = new String(rsa.decrypt(name, KeyType.PrivateKey));
        String userPassword = new String(rsa.decrypt(password, KeyType.PrivateKey));
        String newUserPassword = new String(rsa.decrypt(newPassword, KeyType.PrivateKey));
        if(userService.userPasswordChange(userName,userPassword,newUserPassword)){
            return ResponseEntity.ok("修改成功");
        }else{
            return ResponseEntity.ok("修改失败");
        }
    }

    @ApiOperation("找回密码")
    @PostMapping("/forget")
    public ResponseEntity<String> userPasswordBySms(@RequestParam String name,
                                                    @RequestParam String newPassword,
                                                    @RequestParam String sms){
        RSA rsa = new RSA(privateKey, null);
        String smsTemp = new String(rsa.decrypt(sms,KeyType.PrivateKey));
        String userName = new String(rsa.decrypt(name,KeyType.PrivateKey));
        String newUserPassword = new String(rsa.decrypt(newPassword, KeyType.PrivateKey));
        UserRegister userRegister = userRegisterService.selectById(userName);

        if (userRegister==null){
            return ResponseEntity.ok("账号错误");
        }else if (userRegister.getSms()!=Integer.parseInt(smsTemp)){
            return ResponseEntity.ok("验证码错误");
        }else {
            User user = userService.getUserByName(userName);
            user.setPassword(newUserPassword);
            userService.updateById(user);
            userRegisterService.deleteUserRegisterOk(userName);
            return ResponseEntity.ok("修改成功");
        }
    }

    @ApiOperation("找回密码的验证码")
    @PostMapping("/forget/sms")
    public void userPasswordSms(@RequestParam String name){
        RSA rsa = new RSA(privateKey, null);
        String userName = new String(rsa.decrypt(name,KeyType.PrivateKey));
        int sms = (int)((Math.random()*9+1)*10000);
        mailService.sendSimpleMail("2020302111336@whu.edu.cn",userService.userGetEmail(userName),"**@outlook.com","注册验证码","您的验证码为:"+sms);
        UserRegister userRegister = userRegisterService.selectById(userName);
        if (userRegister==null){
            userRegisterService.addUserRegister(userName,"",sms);
        }else {
            userRegister.setSms(sms);
            userRegisterService.updateUserRegister(userRegister);
        }
    }
}

